How does wealth relate to health?
In this project, we seek to explore the relationships between income levels and health, as income is frequently brought up as one of the social determinants of health. We will explore this relationship at multiple levels: international, national, and local levels.
Two main indicators of health are health outcomes, such as life expectancy, and health insurance coverage. The health insurance is especially a big challenge in the United States, given its highly fragmented healthcare system and payment model. In this project, we aim to explore how these measures vary over time and across geography.
Life expectancy: International, national, state-level
At the international level, we looked at life expectancy as a function of GDP per capita. From 1952 to 2007, life expectancy has increased overall, and we can clearly see that in most countries, as the national wealth increases, the life expectancy also increases.
p <- ggplot(gapminder, aes(x = gdpPercap, y=lifeExp, size = pop, colour = country)) +
geom_point(show.legend = FALSE, alpha = 0.7) +
scale_color_viridis_d() +
scale_size(range = c(2, 12)) +
scale_x_log10() +
theme_economist() +
labs(x="Weath (GDP per capita)",
y="Life expectancy",
title = "Life Expectancy vs. Income in the world",
caption = "Source: IHME")
p <- p + transition_time(year) +
labs(title = "Life expectancy vs. GDP by country: {frame_time}")+
view_follow(fixed_y = TRUE)
anim_save("life.gif")
This pattern continues at the national level in the US: The richest American men live 15 years longer than the poorest men, while the richest American women live 10 years longer than the poorest women.
df1 <- read.csv("Data/health_ineq_online_table_1.csv")
df1 <- df1 %>% mutate(gnd = ifelse(gnd=="F", "Female", "Male"))
p1 <- ggplot(df1, aes(pctile, le_raceadj),alpha = 1)+
geom_line(aes(color=gnd))+
theme_economist() +
labs(x="\nHousehold income percentile",
y="Life expectancy at age 40\n",
title = "Life expectancy vs. income in the US\n",
caption = "Source: Health Inequality Project") +
scale_color_brewer(palette = "Dark2") +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "top", legend.title = element_blank())
p1

df3 <- read.csv("Data/health_ineq_online_table_3_female.csv")
df3_2001 <-gather(df3,incomepetile,life,Q1:Q4,factor_key = TRUE)
name <- c("California", "Texas", "Florida", "New York", "Pennsylvania", "Illinois", "Ohio", "Georgia")
df_sub <- df3_2001%>%
filter(statename %in% name)
p3 <- ggplot(data = df_sub, aes(y = life, x = incomepetile,color = statename, group = statename))+
geom_line(size = 1)+
theme_bw()+
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nHousehold income quartile",
y="Life expectancy at age 40\n",
title = "Female life expectancy vs. income\n",
caption = "Source: Health Inequality Project") +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5))+
theme(legend.position = "right", legend.title = element_blank())
p3

df4 <- read.csv("Data/health_ineq_online_table_3_male.csv")
df4_2001 <-gather(df4,incomepetile,life,Q1:Q4,factor_key = TRUE)
df_sub_2 <- df4_2001%>%
filter(statename %in% name)
p4 <- ggplot(data = df_sub_2, aes(y = life, x = incomepetile,color = statename, group = statename))+
geom_line(size = 1)+
theme_bw()+
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nHousehold income quartile",
y="Life expectancy at age 40\n",
title = "Male life expectancy vs. income\n",
caption = "Source: Health Inequality Project") +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5))+
theme(legend.position = "right", legend.title = element_blank())
p4

Health outcomes at the local level
Diabetes
Diabetes <- read_csv("Data/DiabetesData.csv")
Diabetes <- Diabetes %>%
mutate(STATECOUNTYFP = str_pad(`CountyFIPS`, 5, "left", pad = "0"), Percentage = as.numeric(Percentage))
countydiabetes <- merge(lower48, Diabetes, by = "STATECOUNTYFP", duplicateGeoms = TRUE)
countydiabetesincome <- merge(countydiabetes, Income, by = c("STATECOUNTYFP", "Year"), duplicateGeoms = TRUE) %>%
mutate(year = as.integer(year))
countydiabetesincome$adjustedrate <- countydiabetesincome$Percentage/countydiabetesincome$income_per_capita
This plot demonstrates a clear correlation between diabetes rates and income, with higher income counties having lower rates of diabetes. It also shows that while diabetes has increased everywhere over time, the increases have been far more pronounced for poorer counties. Note especially the sharp spike in rates over 2015-2016
diabetesplot <- ggplot(filter(countydiabetesincome, income_per_capita < 100000),
aes(x = income_per_capita, y = Percentage, color = region_name)) +
geom_jitter(alpha = .7) +
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nIncome per capita",
title = "Diabetes rate vs. income\n",
caption = "Source: CDC") +
scale_y_continuous(labels = function(x) paste0(x, "%")) +
scale_x_continuous(labels = dollar) +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "top", legend.title = element_blank(),
axis.title.y = element_blank())
diabetesplotanim <- diabetesplot + transition_time(year) +
labs(title = "Diabetes rate vs. income: {frame_time}\n")
diabetesplotanim
The first map shows diabetes rates as a percentage of the population for each county in the US. The second maps an adjusted metric, the diabetes ratio/per-capita income ratio. This income-adjusted adjuested ratio is intended to account for variance due to income. Geographic differences in diabetes rates are more muted in the adjusted map, indicating that some of the differences in diabetes levels are actually the result of income clustering.
diabetes <- tm_shape(filter(countydiabetes, Year == "2016")) +
tm_fill(col = "Percentage", title = "", pal = "YlOrRd", n = 5) +
tm_layout(frame = FALSE, legend.format = list(
fun = function(x) paste0(formatC(x, digits = 0, format = "f"), "%")))
tmap_save(diabetes, "diabetes_counties_2016_map.png")
diabetes_adjusted <- tm_shape(filter(countydiabetesincome, Year == "2016")) +
tm_fill(col = "adjustedrate", title = "Diabetes-to-\nincome ratio", pal = "YlOrRd", n = 5) +
tm_layout(frame = FALSE, legend.format = list(
fun = function(x) paste0(formatC(x, digits = 4, format = "f"))))
tmap_save(diabetes_adjusted, "diabetes_income_ratio_counties_2016_map.png")
Life expectancy
LifeExp <- read_csv("Data/ExpectancyData.csv")
LifeExp <- LifeExp %>%
mutate(clean_lifeexp = as.numeric(str_extract(`Life expectancy`, "^\\d*.\\d*")),
STATECOUNTYFP = str_pad(`FIPS`, 5, "left", pad = "0"))
countylife <- merge(lower48, LifeExp, by = "STATECOUNTYFP", duplicateGeoms = TRUE)
countylifeincome <- merge(countylife, Income, by = c("STATECOUNTYFP", "Year"), duplicateGeoms = TRUE) %>%
mutate(year = as.integer(year))
countylifeincome$adjustedrate <- countylifeincome$clean_lifeexp/countylifeincome$income_per_capita
This plot demonstrates a clear relatinoship between life expectancy and income, with higher income counties having higher average life expectancy. There is a worrying pattern of life expectancy increasing for higher-income counties while life expectancy is constant or falling in lower-income counties.
lifeplot <- ggplot(filter(countylifeincome, income_per_capita < 100000),
aes(x = income_per_capita, y = clean_lifeexp, color = region_name)) +
geom_jitter(alpha = .7) +
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nIncome per capita",
title = "Life expectancy vs. income\n",
caption = "Source: IHME") +
scale_x_continuous(labels = dollar) +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "top", legend.title = element_blank(),
axis.title.y = element_blank())
lifeplotanim <- lifeplot + transition_time(year) +
labs(title = "Life expectancy vs. income: {frame_time}")
anim_save("lifeplotanim.gif")
The first map shows life expectancy for each county in the US. The second maps an adjusted metric, life expectancy/income per capita. Geographic differences in life expectancy (intensity of color variation) are significantly more muted in the adjusted map, indicating that much of the variance in life expectancy is the result of income clustering.
Regular map
life_expectancy <- tm_shape(filter(countylife, Year == "2014")) +
tm_fill(col = "clean_lifeexp", title = "", pal = "YlGn", n = 5) +
tm_layout(frame = FALSE, legend.format = list(
fun = function(x) paste0(formatC(x, digits = 0, format = "f"))))
tmap_save(life_expectancy, "life_expectancy_counties_2014_map.png")
life_expectancy_adjusted <- tm_shape(filter(countylifeincome, Year == "2014")) +
tm_fill(col = "adjustedrate", title = "Life expectancy-to-\nincome ratio", pal = "YlGn", n = 5) +
tm_layout(frame = FALSE, legend.format = list(
fun = function(x) paste0(formatC(x, digits = 3, format = "f"))))
tmap_save(life_expectancy_adjusted, "life_expectancy_adjusted_counties_2014_map.png")
Infant mortality
im_data <- read_excel("Data/Linked_Birth_Infant_Death_Records_per_1000_by_County_and_Year_Died_2007-2017.xlsx")
im_data <- im_data %>%
mutate(STATECOUNTYFP = str_pad(`County Code`, 5, "left", pad = "0"),
Deathrate = as.numeric(`Death Rate`))
countyinfant <- merge(lower48, im_data, by = "STATECOUNTYFP", duplicateGeoms = TRUE)
countyinfantincome <- merge(im_data, Income, by = "STATECOUNTYFP", duplicateGeoms = TRUE) %>%
mutate(year = as.integer(year))
countyinfantincome$adjustedrate <- countyinfantincome$Deathrate/countyinfantincome$income_per_capita
Infant mortality shows a clear correlation to income, with higher income counties having lower infant mortality. Neither the pattern nor the overall incidence of child mortality appears to be changing.
infantplot <- ggplot(filter(countyinfantincome, income_per_capita < 100000),
aes(x = income_per_capita, y = Deathrate, color = region_name)) +
geom_jitter(alpha = .7) +
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nIncome per capita",
y = "Deaths per 1,000 live births\n",
title = "Infant mortality vs. income\n",
caption = "Source: CDC") +
scale_x_continuous(labels = dollar) +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "top", legend.title = element_blank())
infantplotanim <- infantplot + transition_time(year) +
labs(title = "Infant mortality vs. income: {frame_time}")
anim_save("infantplotanim.gif")
Health insurance
In this section, we aim to further our investigation of income and health outcomes by adding in the major player in this linkage – healthcare insurance. Specifically, we focus on the uninsured population and aim to use visualizations to showcase the influence of income on uninsurance rate.
Our base data came from the Small Area Health Insurance Estimates (SAHIE) from the Census Bureau, which was extracted from the American Community Survey (ACS) conducted yearly. We narrowed our focus on the period of 2008 to 2018 for data completeness and consistency considerations. We believe the usage of as recent as possible data would be most ideal (for which the latest possible was year 2018), and we aimed to have a long enough period to detect/showcase any trends. We believe 10 years is a good time frame. We also hereby note that the SAHIE only started to utilize the ACS as the basis for its estimates in 2008, prior to which it used the Annual Social and Economic Supplement to the Current Population Survey (CPS ASEC).
Note: The definition of health insurance coverage in the ACS is - “Is this person CURRENTLY covered by [specifically stated] health insurance or health coverage plans?”
# Loading data
sahie_2008 <- read.csv("Data/sahie_2008_FIPS.csv", header = TRUE)
sahie_2009 <- read.csv("Data/sahie_2009_FIPS.csv", header = TRUE)
sahie_2010 <- read.csv("Data/sahie_2010_FIPS.csv", header = TRUE)
sahie_2011 <- read.csv("Data/sahie_2011_FIPS.csv", header = TRUE)
sahie_2012 <- read.csv("Data/sahie_2012_FIPS.csv", header = TRUE)
sahie_2013 <- read.csv("Data/sahie_2013_FIPS.csv", header = TRUE)
sahie_2014 <- read.csv("Data/sahie_2014_FIPS.csv", header = TRUE)
sahie_2015 <- read.csv("Data/sahie_2015_FIPS.csv", header = TRUE)
sahie_2016 <- read.csv("Data/sahie_2016_FIPS.csv", header = TRUE)
sahie_2017 <- read.csv("Data/sahie_2017_FIPS.csv", header = TRUE)
sahie_2018 <- read.csv("Data/sahie_2018_FIPS.csv", header = TRUE)
How are income levels related to the uninsurance rate? We chose to focus on the 138% of the Federal Poverty Level (FPL) and the 250% of FPL. The reasoning is that for the population with income level below the 138% FPL, if their states expanded Medicaid under the Affordable Care Act (ACA, signed into law by President Obama in 2010 and went into effect starting 2014), they may qualify for Medicaid or CHIP. Population that earns an income below the 250% FPL may qualify for out-of-pocket cost assistance on Silver plans sold through the Marketplace.
From the above graphic, we can see that the lower the income, although with some level of assistance, the higher uninsurance rate across the 10 year period. We can also observe clearly that the uninsurance rate dropped significantly between 2013 and 2014, because of the ACA.
Hover over data points of interest
income <- read.csv("Data/Hongjue_BEA_Income_Per_Capita_by_State_1990-2019.csv")
income <- income %>% mutate(fips = ifelse(str_length(GeoFips) < 5, paste0(0, GeoFips), GeoFips)) %>%
select(-GeoFips) %>%
filter(year %in% 2008:2018)
state_simple <- state_0818 %>% select(year, NUI, NIPR, fips)
inc_insur <- left_join(income, state_simple)
p2 <- ggplot(inc_insur, aes(x=NUI/NIPR, y=income_per_capita, color=GeoName, alpha=0.7, shape=as.factor(year),
text = paste('</br> Year: ', year,
'</br> State: ', GeoName,
'</br> Uninsured percentage: ', round(NUI/NIPR,2),
'</br> Income level: ', income_per_capita))) +
geom_point() +
theme_economist() +
scale_color_viridis_d() +
scale_x_continuous(labels = percent_format(accuracy = 1)) +
scale_y_continuous(labels = dollar) +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "none") +
labs(title = "How does income affect the uninsurance rate?", subtitle = "States by color, years by shape") +
xlab("Rate of uninsurance") +
ylab("Income per capita\n")
ggplotly(p2, tooltip = "text", height = 400, width=780) %>%
config(displayModeBar = FALSE) %>%
layout(hoverlabel = list(bgcolor = "white", font = list(family = "Georgia")))
Here is a more detailed look into this income-uninsurance relationship. We can see that, in general, the lower the income per capita (of a certain state in a given year), the higher the state-level uninsured rate. (Note: States are differentiated using color and years are differentiated using shape.)
To visualize this in a map, we created a Leaflet map with separate layers for the uninsurance rate and income level, shown below for the year 2008. Using this visualization we can observe that in general, the northeast and west coast regions had higher incomes per capita, while the souths, midwest, and Alaska were struggling with the highest uninsurance rate.
dt <- inc_insur %>%
mutate(uninsured = round(NUI/NIPR,2), state = as.character(GeoName)) %>%
select(year, state, uninsured, income_per_capita) %>%
mutate_geocode(state)
# dt_year <- dt %>% filter(year==2008)
dt_year <- dt %>% group_by(state) %>%
summarise(income_per_capita=mean(income_per_capita), uninsured=mean(uninsured),
lon=mean(lon), lat=mean(lat)) %>%
mutate(state=as.factor(state))
states.merged <- merge(x=states, y=dt_year, by.x="NAME", by.y="state")
pal1 <- colorBin("YlOrRd", domain = states.merged$uninsured, bins = c(0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3))
pal2 <- colorBin("BuGn", domain = states.merged$income_per_capita, bins = c(20000:85000))
popup = paste("State: ", states.merged@data$NAME,
"<br>Income per capita: ", round(states.merged@data$income_per_capita,2),
"<br>Uninsured rate: ", round(states.merged@data$uninsured,2))
leaflet(states.merged) %>% addTiles() %>%
setView(-96, 37.8, 4) %>%
addPolygons(fillColor = ~pal1(uninsured),
fillOpacity = 0.6, color = "darkgrey", weight = 1.5,
popup = popup, group="Uninsured rate")%>%
addPolygons(fillColor = ~pal2(income_per_capita),
fillOpacity = 1, color = "white", weight = 2.0,
popup = popup, group="Income level") %>%
addLayersControl(
baseGroups = c("Uninsurance rate", "Income level"),
options = layersControlOptions(collapsed = FALSE))
# height="100%", width="100%"
To make it clearer and easier to understand, we created a data table for our users to explore the statistics of their interest:
dt <- inc_insur %>%
mutate(year=as.factor(year), uninsured = round(NUI/NIPR,2)) %>%
select(year, GeoName, uninsured, income_per_capita)
colnames(dt) <- c("Year", "State Name", "Uninsurance Rate", "Income per Capita")
dt %>%
datatable(
filter = list(position = "top"),
options = list(language = list(sSearch = "Filter:")))
LS0tCnRpdGxlOiAnR3JvdXAgQiBGaW5hbCBQcm9qZWN0OiBJbmNvbWUgYW5kIEhlYWx0aGNhcmUnCmF1dGhvcjoKLSBuYW1lOiBIb25nanVlIFdhbmcKLSBuYW1lOiBBbGlzb24gUnlsYW5kCi0gbmFtZTogWHVuIFdlaQotIG5hbWU6IFRvbHUgQnVrb2xhCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCICVZJylgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB5ZXMKICBodG1sX25vdGVib29rOgogICAgZmlnX2NhcHRpb246IHllcwogICAgdGhlbWU6IHVuaXRlZAogICAgdG9jOiB5ZXMKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0UsIGVjaG89RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1YigiZGthaGxlL2dnbWFwIikKbGlicmFyeShnZ21hcCkKbGlicmFyeShodHRwdXYpCnJlZ2lzdGVyX2dvb2dsZShrZXkgPSBTeXMuZ2V0ZW52KCJHT09HTEVfTUFQU19BUElfS0VZIikpCmBgYAoKIyBIb3cgZG9lcyB3ZWFsdGggcmVsYXRlIHRvIGhlYWx0aD8KCkluIHRoaXMgcHJvamVjdCwgd2Ugc2VlayB0byBleHBsb3JlIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gaW5jb21lIGxldmVscyBhbmQgaGVhbHRoLCBhcyBpbmNvbWUgaXMgZnJlcXVlbnRseSBicm91Z2h0IHVwIGFzIG9uZSBvZiB0aGUgc29jaWFsIGRldGVybWluYW50cyBvZiBoZWFsdGguIFdlIHdpbGwgZXhwbG9yZSB0aGlzIHJlbGF0aW9uc2hpcCBhdCBtdWx0aXBsZSBsZXZlbHM6IGludGVybmF0aW9uYWwsIG5hdGlvbmFsLCBhbmQgbG9jYWwgbGV2ZWxzLiAKClR3byBtYWluIGluZGljYXRvcnMgb2YgaGVhbHRoIGFyZSBoZWFsdGggb3V0Y29tZXMsIHN1Y2ggYXMgbGlmZSBleHBlY3RhbmN5LCBhbmQgaGVhbHRoIGluc3VyYW5jZSBjb3ZlcmFnZS4gVGhlIGhlYWx0aCBpbnN1cmFuY2UgaXMgZXNwZWNpYWxseSBhIGJpZyBjaGFsbGVuZ2UgaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIGdpdmVuIGl0cyBoaWdobHkgZnJhZ21lbnRlZCBoZWFsdGhjYXJlIHN5c3RlbSBhbmQgcGF5bWVudCBtb2RlbC4gSW4gdGhpcyBwcm9qZWN0LCB3ZSBhaW0gdG8gZXhwbG9yZSBob3cgdGhlc2UgbWVhc3VyZXMgdmFyeSBvdmVyIHRpbWUgYW5kIGFjcm9zcyBnZW9ncmFwaHkuCgojIyBMaWZlIGV4cGVjdGFuY3k6IEludGVybmF0aW9uYWwsIG5hdGlvbmFsLCBzdGF0ZS1sZXZlbAoKYGBge3IsIGV2YWw9VFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGVjaG89RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoZ2FwbWluZGVyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdnYW5pbWF0ZSkKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShnZ21hcCkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkodG1hcCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShyZ2VvcykKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkocmdkYWwpCmxpYnJhcnkobGVhZnN5bmMpCmxpYnJhcnkoYWNzKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoc3ApCmxpYnJhcnkodGlncmlzKQojbGlicmFyeShzaGlueSkKI2xpYnJhcnkoc2hpbnl0aGVtZXMpCmxpYnJhcnkobWFwdG9vbHMpCmxpYnJhcnkobWFnaWNrKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkodGlkeXRleHQpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoRFQpCmxpYnJhcnkoZ2dhbHQpCmxpYnJhcnkodHJhbnNmb3JtcikKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGhyYnJ0aGVtZXMpCmxpYnJhcnkoZ3JpZEV4dHJhKQojbGlicmFyeSh1cmJubWFwcikKbGlicmFyeSh0aWR5Y2Vuc3VzKQpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoZ2Vvc3BoZXJlKQpsaWJyYXJ5KGx3Z2VvbSkKbGlicmFyeShzZikKYGBgCgpBdCB0aGUgaW50ZXJuYXRpb25hbCBsZXZlbCwgd2UgbG9va2VkIGF0IGxpZmUgZXhwZWN0YW5jeSBhcyBhIGZ1bmN0aW9uIG9mIEdEUCBwZXIgY2FwaXRhLiBGcm9tIDE5NTIgdG8gMjAwNywgbGlmZSBleHBlY3RhbmN5IGhhcyBpbmNyZWFzZWQgb3ZlcmFsbCwgYW5kIHdlIGNhbiBjbGVhcmx5IHNlZSB0aGF0IGluIG1vc3QgY291bnRyaWVzLCBhcyB0aGUgbmF0aW9uYWwgd2VhbHRoIGluY3JlYXNlcywgdGhlIGxpZmUgZXhwZWN0YW5jeSBhbHNvIGluY3JlYXNlcy4KCmBgYHtyLCBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwIDwtIGdncGxvdChnYXBtaW5kZXIsIGFlcyh4ID0gZ2RwUGVyY2FwLCB5PWxpZmVFeHAsIHNpemUgPSBwb3AsIGNvbG91ciA9IGNvdW50cnkpKSArCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEZBTFNFLCBhbHBoYSA9IDAuNykgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZCgpICsKICBzY2FsZV9zaXplKHJhbmdlID0gYygyLCAxMikpICsKICBzY2FsZV94X2xvZzEwKCkgKwogIHRoZW1lX2Vjb25vbWlzdCgpICsKICBsYWJzKHg9IldlYXRoIChHRFAgcGVyIGNhcGl0YSkiLCAKICAgICAgIHk9IkxpZmUgZXhwZWN0YW5jeSIsCiAgICAgICB0aXRsZSA9ICJMaWZlIEV4cGVjdGFuY3kgdnMuIEluY29tZSBpbiB0aGUgd29ybGQiLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IElITUUiKQoKcCA8LSBwICsgdHJhbnNpdGlvbl90aW1lKHllYXIpICsKICBsYWJzKHRpdGxlID0gIkxpZmUgZXhwZWN0YW5jeSB2cy4gR0RQIGJ5IGNvdW50cnk6IHtmcmFtZV90aW1lfSIpKwogIHZpZXdfZm9sbG93KGZpeGVkX3kgPSBUUlVFKQphbmltX3NhdmUoImxpZmUuZ2lmIikKYGBgCiFbTGlmZSBleHBlY3RhbmN5IHZzLiBHRFBdKEltYWdlcy9saWZlLmdpZikKClRoaXMgcGF0dGVybiBjb250aW51ZXMgYXQgdGhlIG5hdGlvbmFsIGxldmVsIGluIHRoZSBVUzogVGhlIHJpY2hlc3QgQW1lcmljYW4gbWVuIGxpdmUgMTUgeWVhcnMgbG9uZ2VyIHRoYW4gdGhlIHBvb3Jlc3QgbWVuLCB3aGlsZSB0aGUgcmljaGVzdCBBbWVyaWNhbiB3b21lbiBsaXZlIDEwIHllYXJzIGxvbmdlciB0aGFuIHRoZSBwb29yZXN0IHdvbWVuLgoKYGBge3IsIGV2YWw9VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZGYxIDwtIHJlYWQuY3N2KCJEYXRhL2hlYWx0aF9pbmVxX29ubGluZV90YWJsZV8xLmNzdiIpCmRmMSA8LSBkZjEgJT4lIG11dGF0ZShnbmQgPSBpZmVsc2UoZ25kPT0iRiIsICJGZW1hbGUiLCAiTWFsZSIpKQoKcDEgPC0gZ2dwbG90KGRmMSwgYWVzKHBjdGlsZSwgbGVfcmFjZWFkaiksYWxwaGEgPSAxKSsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPWduZCkpKwogIHRoZW1lX2Vjb25vbWlzdCgpICsKICBsYWJzKHg9IlxuSG91c2Vob2xkIGluY29tZSBwZXJjZW50aWxlIiwgCiAgICAgICB5PSJMaWZlIGV4cGVjdGFuY3kgYXQgYWdlIDQwXG4iLAogICAgICAgdGl0bGUgPSAiTGlmZSBleHBlY3RhbmN5IHZzLiBpbmNvbWUgaW4gdGhlIFVTXG4iLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IEhlYWx0aCBJbmVxdWFsaXR5IFByb2plY3QiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkLml0YWxpYyIsIGhqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQoKcDEKYGBgCgpgYGB7ciwgZXZhbD1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkZjMgPC0gcmVhZC5jc3YoIkRhdGEvaGVhbHRoX2luZXFfb25saW5lX3RhYmxlXzNfZmVtYWxlLmNzdiIpCgpkZjNfMjAwMSA8LWdhdGhlcihkZjMsaW5jb21lcGV0aWxlLGxpZmUsUTE6UTQsZmFjdG9yX2tleSA9IFRSVUUpCgpuYW1lIDwtIGMoIkNhbGlmb3JuaWEiLCAiVGV4YXMiLCAiRmxvcmlkYSIsICJOZXcgWW9yayIsICJQZW5uc3lsdmFuaWEiLCAiSWxsaW5vaXMiLCAiT2hpbyIsICJHZW9yZ2lhIikKCmRmX3N1YiA8LSBkZjNfMjAwMSU+JQogIGZpbHRlcihzdGF0ZW5hbWUgJWluJSBuYW1lKQoKcDMgPC0gZ2dwbG90KGRhdGEgPSBkZl9zdWIsIGFlcyh5ID0gbGlmZSwgeCA9IGluY29tZXBldGlsZSxjb2xvciA9IHN0YXRlbmFtZSwgZ3JvdXAgPSBzdGF0ZW5hbWUpKSsKICBnZW9tX2xpbmUoc2l6ZSA9IDEpKwogIHRoZW1lX2J3KCkrCiAgdGhlbWVfZWNvbm9taXN0KCkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogIGxhYnMoeD0iXG5Ib3VzZWhvbGQgaW5jb21lIHF1YXJ0aWxlIiwgCiAgICAgICB5PSJMaWZlIGV4cGVjdGFuY3kgYXQgYWdlIDQwXG4iLAogICAgICAgdGl0bGUgPSAiRmVtYWxlIGxpZmUgZXhwZWN0YW5jeSB2cy4gaW5jb21lXG4iLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IEhlYWx0aCBJbmVxdWFsaXR5IFByb2plY3QiKSArCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkLml0YWxpYyIsIGhqdXN0ID0gMC41KSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQoKcDMKYGBgCgpgYGB7ciwgZXZhbD1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkZjQgPC0gcmVhZC5jc3YoIkRhdGEvaGVhbHRoX2luZXFfb25saW5lX3RhYmxlXzNfbWFsZS5jc3YiKQoKZGY0XzIwMDEgPC1nYXRoZXIoZGY0LGluY29tZXBldGlsZSxsaWZlLFExOlE0LGZhY3Rvcl9rZXkgPSBUUlVFKQoKZGZfc3ViXzIgPC0gZGY0XzIwMDElPiUKICBmaWx0ZXIoc3RhdGVuYW1lICVpbiUgbmFtZSkKCnA0IDwtIGdncGxvdChkYXRhID0gZGZfc3ViXzIsIGFlcyh5ID0gbGlmZSwgeCA9IGluY29tZXBldGlsZSxjb2xvciA9IHN0YXRlbmFtZSwgZ3JvdXAgPSBzdGF0ZW5hbWUpKSsKICBnZW9tX2xpbmUoc2l6ZSA9IDEpKwogIHRoZW1lX2J3KCkrCiAgdGhlbWVfZWNvbm9taXN0KCkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogIGxhYnMoeD0iXG5Ib3VzZWhvbGQgaW5jb21lIHF1YXJ0aWxlIiwgCiAgICAgICB5PSJMaWZlIGV4cGVjdGFuY3kgYXQgYWdlIDQwXG4iLAogICAgICAgdGl0bGUgPSAiTWFsZSBsaWZlIGV4cGVjdGFuY3kgdnMuIGluY29tZVxuIiwKICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBIZWFsdGggSW5lcXVhbGl0eSBQcm9qZWN0IikgKwogIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZC5pdGFsaWMiLCBoanVzdCA9IDAuNSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKCnA0CmBgYAoKIyBIZWFsdGggb3V0Y29tZXMgYXQgdGhlIGxvY2FsIGxldmVsCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGluY2x1ZGU9RkFMU0UsIGV2YWw9RkFMU0V9Cmxvd2VyNDggPC0gY291bnRpZXMoc2V0ZGlmZihzdGF0ZS5uYW1lLCBjKCJIYXdhaWkiLCAiQWxhc2thIikpLCBjbGFzcyA9ICJzZiIpCgpsb3dlcjQ4JFNUQVRFQ09VTlRZRlAgPC0gcGFzdGUwKGxvd2VyNDgkU1RBVEVGUCwgbG93ZXI0OCRDT1VOVFlGUCkKCkluY29tZSA8LXJlYWRfY3N2KCJEYXRhL0luY29tZURhdGEuY3N2IikKCkluY29tZSA8LSBJbmNvbWUgJT4lCiAgbXV0YXRlKCBTVEFURUNPVU5UWUZQID0gc3RyX3BhZChgR0VPSURgLCA1LCAibGVmdCIsIHBhZCA9ICIwIiksIFllYXIgPSB5ZWFyKQpgYGAKCiMjIERpYWJldGVzCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGV2YWw9RkFMU0V9CkRpYWJldGVzIDwtIHJlYWRfY3N2KCJEYXRhL0RpYWJldGVzRGF0YS5jc3YiKQoKRGlhYmV0ZXMgPC0gRGlhYmV0ZXMgJT4lCgltdXRhdGUoU1RBVEVDT1VOVFlGUCA9IHN0cl9wYWQoYENvdW50eUZJUFNgLCA1LCAibGVmdCIsIHBhZCA9ICIwIiksIFBlcmNlbnRhZ2UgPSBhcy5udW1lcmljKFBlcmNlbnRhZ2UpKQoKY291bnR5ZGlhYmV0ZXMgPC0gbWVyZ2UobG93ZXI0OCwgRGlhYmV0ZXMsIGJ5ID0gIlNUQVRFQ09VTlRZRlAiLCBkdXBsaWNhdGVHZW9tcyA9IFRSVUUpCgpjb3VudHlkaWFiZXRlc2luY29tZSA8LSBtZXJnZShjb3VudHlkaWFiZXRlcywgSW5jb21lLCBieSA9IGMoIlNUQVRFQ09VTlRZRlAiLCAiWWVhciIpLCBkdXBsaWNhdGVHZW9tcyA9IFRSVUUpICU+JQogIG11dGF0ZSh5ZWFyID0gYXMuaW50ZWdlcih5ZWFyKSkKCmNvdW50eWRpYWJldGVzaW5jb21lJGFkanVzdGVkcmF0ZSA8LSBjb3VudHlkaWFiZXRlc2luY29tZSRQZXJjZW50YWdlL2NvdW50eWRpYWJldGVzaW5jb21lJGluY29tZV9wZXJfY2FwaXRhCmBgYAoKVGhpcyBwbG90IGRlbW9uc3RyYXRlcyBhIGNsZWFyIGNvcnJlbGF0aW9uIGJldHdlZW4gZGlhYmV0ZXMgcmF0ZXMgYW5kIGluY29tZSwgd2l0aCBoaWdoZXIgaW5jb21lIGNvdW50aWVzIGhhdmluZyBsb3dlciByYXRlcyBvZiBkaWFiZXRlcy4gSXQgYWxzbyBzaG93cyB0aGF0IHdoaWxlIGRpYWJldGVzIGhhcyBpbmNyZWFzZWQgZXZlcnl3aGVyZSBvdmVyIHRpbWUsIHRoZSBpbmNyZWFzZXMgaGF2ZSBiZWVuIGZhciBtb3JlIHByb25vdW5jZWQgZm9yIHBvb3JlciBjb3VudGllcy4gTm90ZSBlc3BlY2lhbGx5IHRoZSBzaGFycCBzcGlrZSBpbiByYXRlcyBvdmVyIDIwMTUtMjAxNgoKYGBge3IsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBldmFsPUZBTFNFfQpkaWFiZXRlc3Bsb3QgPC0gZ2dwbG90KGZpbHRlcihjb3VudHlkaWFiZXRlc2luY29tZSwgaW5jb21lX3Blcl9jYXBpdGEgPCAxMDAwMDApLCAKICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IGluY29tZV9wZXJfY2FwaXRhLCB5ID0gUGVyY2VudGFnZSwgY29sb3IgPSByZWdpb25fbmFtZSkpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IC43KSArCiAgdGhlbWVfZWNvbm9taXN0KCkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogIGxhYnMoeD0iXG5JbmNvbWUgcGVyIGNhcGl0YSIsCiAgICAgICB0aXRsZSA9ICJEaWFiZXRlcyByYXRlIHZzLiBpbmNvbWVcbiIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogQ0RDIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBmdW5jdGlvbih4KSBwYXN0ZTAoeCwgIiUiKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBkb2xsYXIpICsKICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQuaXRhbGljIiwgaGp1c3QgPSAwLjUpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSkKCmRpYWJldGVzcGxvdGFuaW0gPC0gZGlhYmV0ZXNwbG90ICsgdHJhbnNpdGlvbl90aW1lKHllYXIpICsKICBsYWJzKHRpdGxlID0gIkRpYWJldGVzIHJhdGUgdnMuIGluY29tZToge2ZyYW1lX3RpbWV9XG4iKQoKZGlhYmV0ZXNwbG90YW5pbQpgYGAKCiFbRGlhYmV0ZXMgJiBJbmNvbWUsIGJ5IHJlZ2lvbl0oSW1hZ2VzL2RpYWJldGVzcGxvdGFuaW0uZ2lmKQoKClRoZSBmaXJzdCBtYXAgc2hvd3MgZGlhYmV0ZXMgcmF0ZXMgYXMgYSBwZXJjZW50YWdlIG9mIHRoZSBwb3B1bGF0aW9uIGZvciBlYWNoIGNvdW50eSBpbiB0aGUgVVMuIFRoZSBzZWNvbmQgbWFwcyBhbiBhZGp1c3RlZCBtZXRyaWMsIHRoZSBkaWFiZXRlcyByYXRpby9wZXItY2FwaXRhIGluY29tZSByYXRpby4gVGhpcyBpbmNvbWUtYWRqdXN0ZWQgYWRqdWVzdGVkIHJhdGlvIGlzIGludGVuZGVkIHRvIGFjY291bnQgZm9yIHZhcmlhbmNlIGR1ZSB0byBpbmNvbWUuIEdlb2dyYXBoaWMgZGlmZmVyZW5jZXMgaW4gZGlhYmV0ZXMgcmF0ZXMgYXJlIG1vcmUgbXV0ZWQgaW4gdGhlIGFkanVzdGVkIG1hcCwgaW5kaWNhdGluZyB0aGF0IHNvbWUgb2YgdGhlIGRpZmZlcmVuY2VzIGluIGRpYWJldGVzIGxldmVscyBhcmUgYWN0dWFsbHkgdGhlIHJlc3VsdCBvZiBpbmNvbWUgY2x1c3RlcmluZy4gCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQpkaWFiZXRlcyA8LSB0bV9zaGFwZShmaWx0ZXIoY291bnR5ZGlhYmV0ZXMsIFllYXIgPT0gIjIwMTYiKSkgKwogIHRtX2ZpbGwoY29sID0gIlBlcmNlbnRhZ2UiLCB0aXRsZSA9ICIiLCBwYWwgPSAiWWxPclJkIiwgbiA9IDUpICsKICB0bV9sYXlvdXQoZnJhbWUgPSBGQUxTRSwgbGVnZW5kLmZvcm1hdCA9IGxpc3QoCiAgICBmdW4gPSBmdW5jdGlvbih4KSBwYXN0ZTAoZm9ybWF0Qyh4LCBkaWdpdHMgPSAwLCBmb3JtYXQgPSAiZiIpLCAiJSIpKSkKCnRtYXBfc2F2ZShkaWFiZXRlcywgImRpYWJldGVzX2NvdW50aWVzXzIwMTZfbWFwLnBuZyIpCmBgYAohW0RpYWJldGVzIHJhdGUgYnkgY291bnR5OiAyMDE2XShJbWFnZXMvZGlhYmV0ZXNfY291bnRpZXNfMjAxNl9tYXAucG5nKQoKYGBge3IsIGV2YWwgPSBGQUxTRX0KZGlhYmV0ZXNfYWRqdXN0ZWQgPC0gdG1fc2hhcGUoZmlsdGVyKGNvdW50eWRpYWJldGVzaW5jb21lLCBZZWFyID09ICIyMDE2IikpICsKICB0bV9maWxsKGNvbCA9ICJhZGp1c3RlZHJhdGUiLCB0aXRsZSA9ICJEaWFiZXRlcy10by1cbmluY29tZSByYXRpbyIsIHBhbCA9ICJZbE9yUmQiLCBuID0gNSkgKwogIHRtX2xheW91dChmcmFtZSA9IEZBTFNFLCBsZWdlbmQuZm9ybWF0ID0gbGlzdCgKICAgIGZ1biA9IGZ1bmN0aW9uKHgpIHBhc3RlMChmb3JtYXRDKHgsIGRpZ2l0cyA9IDQsIGZvcm1hdCA9ICJmIikpKSkKCnRtYXBfc2F2ZShkaWFiZXRlc19hZGp1c3RlZCwgImRpYWJldGVzX2luY29tZV9yYXRpb19jb3VudGllc18yMDE2X21hcC5wbmciKQpgYGAKCiFbRGlhYmV0ZXMgYWRqdXN0ZWQgbWV0cmljIGJ5IGNvdW50eTogMjAxNl0oSW1hZ2VzL2RpYWJldGVzX2luY29tZV9yYXRpb19jb3VudGllc18yMDE2X21hcC5wbmcpCgoKIyMgTGlmZSBleHBlY3RhbmN5CgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGV2YWw9RkFMU0V9CkxpZmVFeHAgPC0gcmVhZF9jc3YoIkRhdGEvRXhwZWN0YW5jeURhdGEuY3N2IikKCkxpZmVFeHAgPC0gTGlmZUV4cCAlPiUKICBtdXRhdGUoY2xlYW5fbGlmZWV4cCA9IGFzLm51bWVyaWMoc3RyX2V4dHJhY3QoYExpZmUgZXhwZWN0YW5jeWAsICJeXFxkKi5cXGQqIikpLCAKICAgICAgICAgU1RBVEVDT1VOVFlGUCA9IHN0cl9wYWQoYEZJUFNgLCA1LCAibGVmdCIsIHBhZCA9ICIwIikpCgpjb3VudHlsaWZlIDwtIG1lcmdlKGxvd2VyNDgsIExpZmVFeHAsIGJ5ID0gIlNUQVRFQ09VTlRZRlAiLCBkdXBsaWNhdGVHZW9tcyA9IFRSVUUpCgpjb3VudHlsaWZlaW5jb21lIDwtIG1lcmdlKGNvdW50eWxpZmUsIEluY29tZSwgYnkgPSBjKCJTVEFURUNPVU5UWUZQIiwgIlllYXIiKSwgZHVwbGljYXRlR2VvbXMgPSBUUlVFKSAlPiUKICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoeWVhcikpCgpjb3VudHlsaWZlaW5jb21lJGFkanVzdGVkcmF0ZSA8LSBjb3VudHlsaWZlaW5jb21lJGNsZWFuX2xpZmVleHAvY291bnR5bGlmZWluY29tZSRpbmNvbWVfcGVyX2NhcGl0YQpgYGAKClRoaXMgcGxvdCBkZW1vbnN0cmF0ZXMgYSBjbGVhciByZWxhdGlub3NoaXAgYmV0d2VlbiBsaWZlIGV4cGVjdGFuY3kgYW5kIGluY29tZSwgd2l0aCBoaWdoZXIgaW5jb21lIGNvdW50aWVzIGhhdmluZyBoaWdoZXIgYXZlcmFnZSBsaWZlIGV4cGVjdGFuY3kuIFRoZXJlIGlzIGEgd29ycnlpbmcgcGF0dGVybiBvZiBsaWZlIGV4cGVjdGFuY3kgaW5jcmVhc2luZyBmb3IgaGlnaGVyLWluY29tZSBjb3VudGllcyB3aGlsZSBsaWZlIGV4cGVjdGFuY3kgaXMgY29uc3RhbnQgb3IgZmFsbGluZyBpbiBsb3dlci1pbmNvbWUgY291bnRpZXMuIAoKYGBge3IsIGV2YWwgPSBGQUxTRX0KbGlmZXBsb3QgPC0gZ2dwbG90KGZpbHRlcihjb3VudHlsaWZlaW5jb21lLCBpbmNvbWVfcGVyX2NhcGl0YSA8IDEwMDAwMCksIAogICAgICAgICAgICAgICAgICAgYWVzKHggPSBpbmNvbWVfcGVyX2NhcGl0YSwgeSA9IGNsZWFuX2xpZmVleHAsIGNvbG9yID0gcmVnaW9uX25hbWUpKSArCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAuNykgKwogIHRoZW1lX2Vjb25vbWlzdCgpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsKICBsYWJzKHg9IlxuSW5jb21lIHBlciBjYXBpdGEiLAogICAgICAgdGl0bGUgPSAiTGlmZSBleHBlY3RhbmN5IHZzLiBpbmNvbWVcbiIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogSUhNRSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gZG9sbGFyKSArCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkLml0YWxpYyIsIGhqdXN0ID0gMC41KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpsaWZlcGxvdGFuaW0gPC0gbGlmZXBsb3QgKyB0cmFuc2l0aW9uX3RpbWUoeWVhcikgKwogIGxhYnModGl0bGUgPSAiTGlmZSBleHBlY3RhbmN5IHZzLiBpbmNvbWU6IHtmcmFtZV90aW1lfSIpCgphbmltX3NhdmUoImxpZmVwbG90YW5pbS5naWYiKQpgYGAKCiFbTGlmZSBFeHBlY3RhbmN5ICYgSW5jb21lLCBieSByZWdpb25dKEltYWdlcy9saWZlcGxvdGFuaW0uZ2lmKQoKClRoZSBmaXJzdCBtYXAgc2hvd3MgbGlmZSBleHBlY3RhbmN5IGZvciBlYWNoIGNvdW50eSBpbiB0aGUgVVMuIFRoZSBzZWNvbmQgbWFwcyBhbiBhZGp1c3RlZCBtZXRyaWMsIGxpZmUgZXhwZWN0YW5jeS9pbmNvbWUgcGVyIGNhcGl0YS4gR2VvZ3JhcGhpYyBkaWZmZXJlbmNlcyBpbiBsaWZlIGV4cGVjdGFuY3kgKGludGVuc2l0eSBvZiBjb2xvciB2YXJpYXRpb24pIGFyZSBzaWduaWZpY2FudGx5IG1vcmUgbXV0ZWQgaW4gdGhlIGFkanVzdGVkIG1hcCwgaW5kaWNhdGluZyB0aGF0IG11Y2ggb2YgdGhlIHZhcmlhbmNlIGluIGxpZmUgZXhwZWN0YW5jeSBpcyB0aGUgcmVzdWx0IG9mIGluY29tZSBjbHVzdGVyaW5nLiAKCiMjIFJlZ3VsYXIgbWFwCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQpsaWZlX2V4cGVjdGFuY3kgPC0gdG1fc2hhcGUoZmlsdGVyKGNvdW50eWxpZmUsIFllYXIgPT0gIjIwMTQiKSkgKwogIHRtX2ZpbGwoY29sID0gImNsZWFuX2xpZmVleHAiLCB0aXRsZSA9ICIiLCBwYWwgPSAiWWxHbiIsIG4gPSA1KSArCiAgdG1fbGF5b3V0KGZyYW1lID0gRkFMU0UsIGxlZ2VuZC5mb3JtYXQgPSBsaXN0KAogICAgZnVuID0gZnVuY3Rpb24oeCkgcGFzdGUwKGZvcm1hdEMoeCwgZGlnaXRzID0gMCwgZm9ybWF0ID0gImYiKSkpKQoKdG1hcF9zYXZlKGxpZmVfZXhwZWN0YW5jeSwgImxpZmVfZXhwZWN0YW5jeV9jb3VudGllc18yMDE0X21hcC5wbmciKQpgYGAKIVtMaWZlIGV4cGVjdGFuY3kgYnkgY291bnR5OiAyMDE0XShJbWFnZXMvbGlmZV9leHBlY3RhbmN5X2NvdW50aWVzXzIwMTRfbWFwLnBuZykKCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQpsaWZlX2V4cGVjdGFuY3lfYWRqdXN0ZWQgPC0gdG1fc2hhcGUoZmlsdGVyKGNvdW50eWxpZmVpbmNvbWUsIFllYXIgPT0gIjIwMTQiKSkgKwogIHRtX2ZpbGwoY29sID0gImFkanVzdGVkcmF0ZSIsIHRpdGxlID0gIkxpZmUgZXhwZWN0YW5jeS10by1cbmluY29tZSByYXRpbyIsIHBhbCA9ICJZbEduIiwgbiA9IDUpICsKICB0bV9sYXlvdXQoZnJhbWUgPSBGQUxTRSwgbGVnZW5kLmZvcm1hdCA9IGxpc3QoCiAgICBmdW4gPSBmdW5jdGlvbih4KSBwYXN0ZTAoZm9ybWF0Qyh4LCBkaWdpdHMgPSAzLCBmb3JtYXQgPSAiZiIpKSkpCgp0bWFwX3NhdmUobGlmZV9leHBlY3RhbmN5X2FkanVzdGVkLCAibGlmZV9leHBlY3RhbmN5X2FkanVzdGVkX2NvdW50aWVzXzIwMTRfbWFwLnBuZyIpCmBgYAohW0xpZmUgZXhwZWN0YW5jeSBhZGp1c3RlZCBtZXRyaWMgYnkgY291bnR5OiAyMDE0XShJbWFnZXMvbGlmZV9leHBlY3RhbmN5X2FkanVzdGVkX2NvdW50aWVzXzIwMTRfbWFwLnBuZykKCgojIyBJbmZhbnQgbW9ydGFsaXR5IAoKYGBge3IsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBldmFsPUZBTFNFfQppbV9kYXRhIDwtIHJlYWRfZXhjZWwoIkRhdGEvTGlua2VkX0JpcnRoX0luZmFudF9EZWF0aF9SZWNvcmRzX3Blcl8xMDAwX2J5X0NvdW50eV9hbmRfWWVhcl9EaWVkXzIwMDctMjAxNy54bHN4IikKCmltX2RhdGEgPC0gaW1fZGF0YSAlPiUKICBtdXRhdGUoU1RBVEVDT1VOVFlGUCA9IHN0cl9wYWQoYENvdW50eSBDb2RlYCwgNSwgImxlZnQiLCBwYWQgPSAiMCIpLCAKICAgICAgICAgRGVhdGhyYXRlID0gYXMubnVtZXJpYyhgRGVhdGggUmF0ZWApKQoKY291bnR5aW5mYW50IDwtIG1lcmdlKGxvd2VyNDgsIGltX2RhdGEsIGJ5ID0gIlNUQVRFQ09VTlRZRlAiLCBkdXBsaWNhdGVHZW9tcyA9IFRSVUUpCgpjb3VudHlpbmZhbnRpbmNvbWUgPC0gbWVyZ2UoaW1fZGF0YSwgSW5jb21lLCBieSA9ICJTVEFURUNPVU5UWUZQIiwgZHVwbGljYXRlR2VvbXMgPSBUUlVFKSAlPiUKICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoeWVhcikpCgpjb3VudHlpbmZhbnRpbmNvbWUkYWRqdXN0ZWRyYXRlIDwtIGNvdW50eWluZmFudGluY29tZSREZWF0aHJhdGUvY291bnR5aW5mYW50aW5jb21lJGluY29tZV9wZXJfY2FwaXRhCmBgYAoKSW5mYW50IG1vcnRhbGl0eSBzaG93cyBhIGNsZWFyIGNvcnJlbGF0aW9uIHRvIGluY29tZSwgd2l0aCBoaWdoZXIgaW5jb21lIGNvdW50aWVzIGhhdmluZyBsb3dlciBpbmZhbnQgbW9ydGFsaXR5LiBOZWl0aGVyIHRoZSBwYXR0ZXJuIG5vciB0aGUgb3ZlcmFsbCBpbmNpZGVuY2Ugb2YgY2hpbGQgbW9ydGFsaXR5IGFwcGVhcnMgdG8gYmUgY2hhbmdpbmcuCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGV2YWw9RkFMU0V9CmluZmFudHBsb3QgPC0gZ2dwbG90KGZpbHRlcihjb3VudHlpbmZhbnRpbmNvbWUsIGluY29tZV9wZXJfY2FwaXRhIDwgMTAwMDAwKSwgCiAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gaW5jb21lX3Blcl9jYXBpdGEsIHkgPSBEZWF0aHJhdGUsIGNvbG9yID0gcmVnaW9uX25hbWUpKSArCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAuNykgKwogIHRoZW1lX2Vjb25vbWlzdCgpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsKICBsYWJzKHg9IlxuSW5jb21lIHBlciBjYXBpdGEiLAogICAgICAgeSA9ICJEZWF0aHMgcGVyIDEsMDAwIGxpdmUgYmlydGhzXG4iLAogICAgICAgdGl0bGUgPSAiSW5mYW50IG1vcnRhbGl0eSB2cy4gaW5jb21lXG4iLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IENEQyIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gZG9sbGFyKSArCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkLml0YWxpYyIsIGhqdXN0ID0gMC41KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKCmluZmFudHBsb3RhbmltIDwtIGluZmFudHBsb3QgKyB0cmFuc2l0aW9uX3RpbWUoeWVhcikgKwogIGxhYnModGl0bGUgPSAiSW5mYW50IG1vcnRhbGl0eSB2cy4gaW5jb21lOiB7ZnJhbWVfdGltZX0iKQoKYW5pbV9zYXZlKCJpbmZhbnRwbG90YW5pbS5naWYiKQpgYGAKCiFbSW5mYW50IG1vcnRhbGl0eSAmIEluY29tZSwgYnkgcmVnaW9uXShJbWFnZXMvaW5mYW50cGxvdGFuaW0uZ2lmKQoKCgojIEhlYWx0aCBpbnN1cmFuY2UKCkluIHRoaXMgc2VjdGlvbiwgd2UgYWltIHRvIGZ1cnRoZXIgb3VyIGludmVzdGlnYXRpb24gb2YgaW5jb21lIGFuZCBoZWFsdGggb3V0Y29tZXMgYnkgYWRkaW5nIGluIHRoZSBtYWpvciBwbGF5ZXIgaW4gdGhpcyBsaW5rYWdlIC0tIGhlYWx0aGNhcmUgaW5zdXJhbmNlLiBTcGVjaWZpY2FsbHksIHdlIGZvY3VzIG9uIHRoZSB1bmluc3VyZWQgcG9wdWxhdGlvbiBhbmQgYWltIHRvIHVzZSB2aXN1YWxpemF0aW9ucyB0byBzaG93Y2FzZSB0aGUgaW5mbHVlbmNlIG9mIGluY29tZSBvbiB1bmluc3VyYW5jZSByYXRlLiAKCk91ciBiYXNlIGRhdGEgY2FtZSBmcm9tIHRoZSBTbWFsbCBBcmVhIEhlYWx0aCBJbnN1cmFuY2UgRXN0aW1hdGVzIChTQUhJRSkgZnJvbSB0aGUgQ2Vuc3VzIEJ1cmVhdSwgd2hpY2ggd2FzIGV4dHJhY3RlZCBmcm9tIHRoZSBBbWVyaWNhbiBDb21tdW5pdHkgU3VydmV5IChBQ1MpIGNvbmR1Y3RlZCB5ZWFybHkuIFdlIG5hcnJvd2VkIG91ciBmb2N1cyBvbiB0aGUgcGVyaW9kIG9mIDIwMDggdG8gMjAxOCBmb3IgZGF0YSBjb21wbGV0ZW5lc3MgYW5kIGNvbnNpc3RlbmN5IGNvbnNpZGVyYXRpb25zLiBXZSBiZWxpZXZlIHRoZSB1c2FnZSBvZiBhcyByZWNlbnQgYXMgcG9zc2libGUgZGF0YSB3b3VsZCBiZSBtb3N0IGlkZWFsIChmb3Igd2hpY2ggdGhlIGxhdGVzdCBwb3NzaWJsZSB3YXMgeWVhciAyMDE4KSwgYW5kIHdlIGFpbWVkIHRvIGhhdmUgYSBsb25nIGVub3VnaCBwZXJpb2QgdG8gZGV0ZWN0L3Nob3djYXNlIGFueSB0cmVuZHMuIFdlIGJlbGlldmUgMTAgeWVhcnMgaXMgYSBnb29kIHRpbWUgZnJhbWUuIFdlIGFsc28gaGVyZWJ5IG5vdGUgdGhhdCB0aGUgU0FISUUgb25seSBzdGFydGVkIHRvIHV0aWxpemUgdGhlIEFDUyBhcyB0aGUgYmFzaXMgZm9yIGl0cyBlc3RpbWF0ZXMgaW4gMjAwOCwgcHJpb3IgdG8gd2hpY2ggaXQgdXNlZCB0aGUgQW5udWFsIFNvY2lhbCBhbmQgRWNvbm9taWMgU3VwcGxlbWVudCB0byB0aGUgQ3VycmVudCBQb3B1bGF0aW9uIFN1cnZleSAoQ1BTIEFTRUMpLgoKTm90ZTogVGhlIGRlZmluaXRpb24gb2YgaGVhbHRoIGluc3VyYW5jZSBjb3ZlcmFnZSBpbiB0aGUgQUNTIGlzIC0gIklzIHRoaXMgcGVyc29uICoqQ1VSUkVOVExZKiogY292ZXJlZCBieSBbc3BlY2lmaWNhbGx5IHN0YXRlZF0gaGVhbHRoIGluc3VyYW5jZSBvciBoZWFsdGggY292ZXJhZ2UgcGxhbnM/IgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgTG9hZGluZyBkYXRhCgpzYWhpZV8yMDA4IDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMDhfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDA5IDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMDlfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDEwIDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMTBfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDExIDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMTFfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDEyIDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMTJfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDEzIDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMTNfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDE0IDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMTRfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDE1IDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMTVfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDE2IDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMTZfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDE3IDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMTdfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzYWhpZV8yMDE4IDwtIHJlYWQuY3N2KCJEYXRhL3NhaGllXzIwMThfRklQUy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQojIENsZWFuaW5nIGRhdGEKc2FoaWVfMjAwOCA8LSBzYWhpZV8yMDA4ICU+JSAKICBzZWxlY3QoeWVhcixhZ2VjYXQscmFjZWNhdCxzZXhjYXQsaXByY2F0LE5JUFIsTlVJLE5JQyxQQ1RVSSxQQ1RJQyxQQ1RFTElHLFBDVExJSUMsCiAgICAgICAgIHN0YXRlX25hbWUsIGNvdW50eV9uYW1lLCBmaXBzKSAlPiUKICBtdXRhdGUoTklQUj1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JUFIpKSkpLAogICAgICAgICBOVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOVUkpKSkpLAogICAgICAgICBOSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSUMpKSkpLAogICAgICAgICBQQ1RVST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVFVJKSkpKSwKICAgICAgICAgUENUSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RJQykpKSksCiAgICAgICAgIFBDVEVMSUc9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RFTElHKSkpKSwKICAgICAgICAgUENUTElJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVExJSUMpKSkpLAogICAgICAgICBzdGF0ZV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoc3RhdGVfbmFtZSkpLGNvdW50eV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoY291bnR5X25hbWUpKSkgJT4lCiAgbXV0YXRlKGZpcHMgPSBpZmVsc2Uoc3RyX2xlbmd0aChmaXBzKSA8IDUsIHBhc3RlMCgwLCBmaXBzKSwgZmlwcykpCnNhaGllXzIwMDkgPC0gc2FoaWVfMjAwOSAlPiUgCiAgc2VsZWN0KHllYXIsYWdlY2F0LHJhY2VjYXQsc2V4Y2F0LGlwcmNhdCxOSVBSLE5VSSxOSUMsUENUVUksUENUSUMsUENURUxJRyxQQ1RMSUlDLAogICAgICAgICBzdGF0ZV9uYW1lLCBjb3VudHlfbmFtZSwgZmlwcykgJT4lCiAgbXV0YXRlKE5JUFI9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSVBSKSkpKSwKICAgICAgICAgTlVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTlVJKSkpKSwKICAgICAgICAgTklDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklDKSkpKSwKICAgICAgICAgUENUVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RVSSkpKSksCiAgICAgICAgIFBDVElDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUSUMpKSkpLAogICAgICAgICBQQ1RFTElHPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENURUxJRykpKSksCiAgICAgICAgIFBDVExJSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RMSUlDKSkpKSwKICAgICAgICAgc3RhdGVfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKHN0YXRlX25hbWUpKSxjb3VudHlfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKGNvdW50eV9uYW1lKSkpICU+JQogIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoZmlwcykgPCA1LCBwYXN0ZTAoMCwgZmlwcyksIGZpcHMpKQpzYWhpZV8yMDEwIDwtIHNhaGllXzIwMTAgJT4lIAogIHNlbGVjdCh5ZWFyLGFnZWNhdCxyYWNlY2F0LHNleGNhdCxpcHJjYXQsTklQUixOVUksTklDLFBDVFVJLFBDVElDLFBDVEVMSUcsUENUTElJQywKICAgICAgICAgc3RhdGVfbmFtZSwgY291bnR5X25hbWUsIGZpcHMpICU+JQogIG11dGF0ZShOSVBSPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklQUikpKSksCiAgICAgICAgIE5VST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5VSSkpKSksCiAgICAgICAgIE5JQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JQykpKSksCiAgICAgICAgIFBDVFVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUVUkpKSkpLAogICAgICAgICBQQ1RJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVElDKSkpKSwKICAgICAgICAgUENURUxJRz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVEVMSUcpKSkpLAogICAgICAgICBQQ1RMSUlDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUTElJQykpKSksCiAgICAgICAgIHN0YXRlX25hbWU9dHJpbXdzKGFzLmNoYXJhY3RlcihzdGF0ZV9uYW1lKSksY291bnR5X25hbWU9dHJpbXdzKGFzLmNoYXJhY3Rlcihjb3VudHlfbmFtZSkpKSAlPiUKICBtdXRhdGUoZmlwcyA9IGlmZWxzZShzdHJfbGVuZ3RoKGZpcHMpIDwgNSwgcGFzdGUwKDAsIGZpcHMpLCBmaXBzKSkKc2FoaWVfMjAxMSA8LSBzYWhpZV8yMDExICU+JSAKICBzZWxlY3QoeWVhcixhZ2VjYXQscmFjZWNhdCxzZXhjYXQsaXByY2F0LE5JUFIsTlVJLE5JQyxQQ1RVSSxQQ1RJQyxQQ1RFTElHLFBDVExJSUMsCiAgICAgICAgIHN0YXRlX25hbWUsIGNvdW50eV9uYW1lLCBmaXBzKSAlPiUKICBtdXRhdGUoTklQUj1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JUFIpKSkpLAogICAgICAgICBOVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOVUkpKSkpLAogICAgICAgICBOSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSUMpKSkpLAogICAgICAgICBQQ1RVST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVFVJKSkpKSwKICAgICAgICAgUENUSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RJQykpKSksCiAgICAgICAgIFBDVEVMSUc9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RFTElHKSkpKSwKICAgICAgICAgUENUTElJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVExJSUMpKSkpLAogICAgICAgICBzdGF0ZV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoc3RhdGVfbmFtZSkpLGNvdW50eV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoY291bnR5X25hbWUpKSkgJT4lCiAgbXV0YXRlKGZpcHMgPSBpZmVsc2Uoc3RyX2xlbmd0aChmaXBzKSA8IDUsIHBhc3RlMCgwLCBmaXBzKSwgZmlwcykpCnNhaGllXzIwMTIgPC0gc2FoaWVfMjAxMiAlPiUgCiAgc2VsZWN0KHllYXIsYWdlY2F0LHJhY2VjYXQsc2V4Y2F0LGlwcmNhdCxOSVBSLE5VSSxOSUMsUENUVUksUENUSUMsUENURUxJRyxQQ1RMSUlDLAogICAgICAgICBzdGF0ZV9uYW1lLCBjb3VudHlfbmFtZSwgZmlwcykgJT4lCiAgbXV0YXRlKE5JUFI9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSVBSKSkpKSwKICAgICAgICAgTlVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTlVJKSkpKSwKICAgICAgICAgTklDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklDKSkpKSwKICAgICAgICAgUENUVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RVSSkpKSksCiAgICAgICAgIFBDVElDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUSUMpKSkpLAogICAgICAgICBQQ1RFTElHPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENURUxJRykpKSksCiAgICAgICAgIFBDVExJSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RMSUlDKSkpKSwKICAgICAgICAgc3RhdGVfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKHN0YXRlX25hbWUpKSxjb3VudHlfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKGNvdW50eV9uYW1lKSkpICU+JQogIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoZmlwcykgPCA1LCBwYXN0ZTAoMCwgZmlwcyksIGZpcHMpKQpzYWhpZV8yMDEzIDwtIHNhaGllXzIwMTMgJT4lIAogIHNlbGVjdCh5ZWFyLGFnZWNhdCxyYWNlY2F0LHNleGNhdCxpcHJjYXQsTklQUixOVUksTklDLFBDVFVJLFBDVElDLFBDVEVMSUcsUENUTElJQywKICAgICAgICAgc3RhdGVfbmFtZSwgY291bnR5X25hbWUsIGZpcHMpICU+JQogIG11dGF0ZShOSVBSPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklQUikpKSksCiAgICAgICAgIE5VST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5VSSkpKSksCiAgICAgICAgIE5JQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JQykpKSksCiAgICAgICAgIFBDVFVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUVUkpKSkpLAogICAgICAgICBQQ1RJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVElDKSkpKSwKICAgICAgICAgUENURUxJRz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVEVMSUcpKSkpLAogICAgICAgICBQQ1RMSUlDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUTElJQykpKSksCiAgICAgICAgIHN0YXRlX25hbWU9dHJpbXdzKGFzLmNoYXJhY3RlcihzdGF0ZV9uYW1lKSksY291bnR5X25hbWU9dHJpbXdzKGFzLmNoYXJhY3Rlcihjb3VudHlfbmFtZSkpKSAlPiUKICBtdXRhdGUoZmlwcyA9IGlmZWxzZShzdHJfbGVuZ3RoKGZpcHMpIDwgNSwgcGFzdGUwKDAsIGZpcHMpLCBmaXBzKSkKc2FoaWVfMjAxNCA8LSBzYWhpZV8yMDE0ICU+JSAKICBzZWxlY3QoeWVhcixhZ2VjYXQscmFjZWNhdCxzZXhjYXQsaXByY2F0LE5JUFIsTlVJLE5JQyxQQ1RVSSxQQ1RJQyxQQ1RFTElHLFBDVExJSUMsCiAgICAgICAgIHN0YXRlX25hbWUsIGNvdW50eV9uYW1lLCBmaXBzKSAlPiUKICBtdXRhdGUoTklQUj1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JUFIpKSkpLAogICAgICAgICBOVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOVUkpKSkpLAogICAgICAgICBOSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSUMpKSkpLAogICAgICAgICBQQ1RVST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVFVJKSkpKSwKICAgICAgICAgUENUSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RJQykpKSksCiAgICAgICAgIFBDVEVMSUc9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RFTElHKSkpKSwKICAgICAgICAgUENUTElJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVExJSUMpKSkpLAogICAgICAgICBzdGF0ZV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoc3RhdGVfbmFtZSkpLGNvdW50eV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoY291bnR5X25hbWUpKSkgJT4lCiAgbXV0YXRlKGZpcHMgPSBpZmVsc2Uoc3RyX2xlbmd0aChmaXBzKSA8IDUsIHBhc3RlMCgwLCBmaXBzKSwgZmlwcykpCnNhaGllXzIwMTUgPC0gc2FoaWVfMjAxNSAlPiUgCiAgc2VsZWN0KHllYXIsYWdlY2F0LHJhY2VjYXQsc2V4Y2F0LGlwcmNhdCxOSVBSLE5VSSxOSUMsUENUVUksUENUSUMsUENURUxJRyxQQ1RMSUlDLAogICAgICAgICBzdGF0ZV9uYW1lLCBjb3VudHlfbmFtZSwgZmlwcykgJT4lCiAgbXV0YXRlKE5JUFI9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSVBSKSkpKSwKICAgICAgICAgTlVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTlVJKSkpKSwKICAgICAgICAgTklDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklDKSkpKSwKICAgICAgICAgUENUVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RVSSkpKSksCiAgICAgICAgIFBDVElDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUSUMpKSkpLAogICAgICAgICBQQ1RFTElHPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENURUxJRykpKSksCiAgICAgICAgIFBDVExJSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RMSUlDKSkpKSwKICAgICAgICAgc3RhdGVfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKHN0YXRlX25hbWUpKSxjb3VudHlfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKGNvdW50eV9uYW1lKSkpICU+JQogIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoZmlwcykgPCA1LCBwYXN0ZTAoMCwgZmlwcyksIGZpcHMpKQpzYWhpZV8yMDE2IDwtIHNhaGllXzIwMTYgJT4lIAogIHNlbGVjdCh5ZWFyLGFnZWNhdCxyYWNlY2F0LHNleGNhdCxpcHJjYXQsTklQUixOVUksTklDLFBDVFVJLFBDVElDLFBDVEVMSUcsUENUTElJQywKICAgICAgICAgc3RhdGVfbmFtZSwgY291bnR5X25hbWUsIGZpcHMpICU+JQogIG11dGF0ZShOSVBSPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklQUikpKSksCiAgICAgICAgIE5VST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5VSSkpKSksCiAgICAgICAgIE5JQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JQykpKSksCiAgICAgICAgIFBDVFVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUVUkpKSkpLAogICAgICAgICBQQ1RJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVElDKSkpKSwKICAgICAgICAgUENURUxJRz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVEVMSUcpKSkpLAogICAgICAgICBQQ1RMSUlDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUTElJQykpKSksCiAgICAgICAgIHN0YXRlX25hbWU9dHJpbXdzKGFzLmNoYXJhY3RlcihzdGF0ZV9uYW1lKSksY291bnR5X25hbWU9dHJpbXdzKGFzLmNoYXJhY3Rlcihjb3VudHlfbmFtZSkpKSAlPiUKICBtdXRhdGUoZmlwcyA9IGlmZWxzZShzdHJfbGVuZ3RoKGZpcHMpIDwgNSwgcGFzdGUwKDAsIGZpcHMpLCBmaXBzKSkKc2FoaWVfMjAxNyA8LSBzYWhpZV8yMDE3ICU+JSAKICBzZWxlY3QoeWVhcixhZ2VjYXQscmFjZWNhdCxzZXhjYXQsaXByY2F0LE5JUFIsTlVJLE5JQyxQQ1RVSSxQQ1RJQyxQQ1RFTElHLFBDVExJSUMsCiAgICAgICAgIHN0YXRlX25hbWUsIGNvdW50eV9uYW1lLCBmaXBzKSAlPiUKICBtdXRhdGUoTklQUj1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JUFIpKSkpLAogICAgICAgICBOVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOVUkpKSkpLAogICAgICAgICBOSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSUMpKSkpLAogICAgICAgICBQQ1RVST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVFVJKSkpKSwKICAgICAgICAgUENUSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RJQykpKSksCiAgICAgICAgIFBDVEVMSUc9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RFTElHKSkpKSwKICAgICAgICAgUENUTElJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVExJSUMpKSkpLAogICAgICAgICBzdGF0ZV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoc3RhdGVfbmFtZSkpLGNvdW50eV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoY291bnR5X25hbWUpKSkgJT4lCiAgbXV0YXRlKGZpcHMgPSBpZmVsc2Uoc3RyX2xlbmd0aChmaXBzKSA8IDUsIHBhc3RlMCgwLCBmaXBzKSwgZmlwcykpCnNhaGllXzIwMTggPC0gc2FoaWVfMjAxOCAlPiUgCiAgc2VsZWN0KHllYXIsYWdlY2F0LHJhY2VjYXQsc2V4Y2F0LGlwcmNhdCxOSVBSLE5VSSxOSUMsUENUVUksUENUSUMsUENURUxJRyxQQ1RMSUlDLAogICAgICAgICBzdGF0ZV9uYW1lLCBjb3VudHlfbmFtZSwgZmlwcykgJT4lCiAgbXV0YXRlKE5JUFI9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSVBSKSkpKSwKICAgICAgICAgTlVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTlVJKSkpKSwKICAgICAgICAgTklDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklDKSkpKSwKICAgICAgICAgUENUVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RVSSkpKSksCiAgICAgICAgIFBDVElDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUSUMpKSkpLAogICAgICAgICBQQ1RFTElHPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENURUxJRykpKSksCiAgICAgICAgIFBDVExJSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RMSUlDKSkpKSwKICAgICAgICAgc3RhdGVfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKHN0YXRlX25hbWUpKSxjb3VudHlfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKGNvdW50eV9uYW1lKSkpICU+JQogIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoZmlwcykgPCA1LCBwYXN0ZTAoMCwgZmlwcyksIGZpcHMpKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQojIE9yZ2FuaXplIGJ5IGNvdW50aWVzCgpjb3VudHlfMjAwOCA8LSBzYWhpZV8yMDA4ICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAwOSA8LSBzYWhpZV8yMDA5ICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxMCA8LSBzYWhpZV8yMDEwICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxMSA8LSBzYWhpZV8yMDExICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxMiA8LSBzYWhpZV8yMDEyICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxMyA8LSBzYWhpZV8yMDEzICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxNCA8LSBzYWhpZV8yMDE0ICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxNSA8LSBzYWhpZV8yMDE1ICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxNiA8LSBzYWhpZV8yMDE2ICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxNyA8LSBzYWhpZV8yMDE3ICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpjb3VudHlfMjAxOCA8LSBzYWhpZV8yMDE4ICU+JSBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lICE9ICIiKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQojIE9yZ2FuaXplIGJ5IHN0YXRlcwoKc3RhdGVfMjAwOCA8LSBzYWhpZV8yMDA4ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAwOSA8LSBzYWhpZV8yMDA5ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxMCA8LSBzYWhpZV8yMDEwICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxMSA8LSBzYWhpZV8yMDExICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxMiA8LSBzYWhpZV8yMDEyICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxMyA8LSBzYWhpZV8yMDEzICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxNCA8LSBzYWhpZV8yMDE0ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxNSA8LSBzYWhpZV8yMDE1ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxNiA8LSBzYWhpZV8yMDE2ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxNyA8LSBzYWhpZV8yMDE3ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMjAxOCA8LSBzYWhpZV8yMDE4ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMCAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKc3RhdGVfMDgxOCA8LSByYmluZChzdGF0ZV8yMDA4LCBzdGF0ZV8yMDA5LCBzdGF0ZV8yMDEwLCBzdGF0ZV8yMDExLCBzdGF0ZV8yMDEyLCAKICAgICAgICAgICAgICAgICAgICBzdGF0ZV8yMDEzLCBzdGF0ZV8yMDE0LCBzdGF0ZV8yMDE1LCBzdGF0ZV8yMDE2LCBzdGF0ZV8yMDE3LCBzdGF0ZV8yMDE4KQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQpwMTM4X3N0YXRlXzIwMDggPC0gc2FoaWVfMjAwOCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDMgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAxMzhfc3RhdGVfMjAwOSA8LSBzYWhpZV8yMDA5ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMyAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDEzOF9zdGF0ZV8yMDEwIDwtIHNhaGllXzIwMTAgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAzICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMTM4X3N0YXRlXzIwMTEgPC0gc2FoaWVfMjAxMSAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDMgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAxMzhfc3RhdGVfMjAxMiA8LSBzYWhpZV8yMDEyICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMyAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDEzOF9zdGF0ZV8yMDEzIDwtIHNhaGllXzIwMTMgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAzICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMTM4X3N0YXRlXzIwMTQgPC0gc2FoaWVfMjAxNCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDMgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAxMzhfc3RhdGVfMjAxNSA8LSBzYWhpZV8yMDE1ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMyAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDEzOF9zdGF0ZV8yMDE2IDwtIHNhaGllXzIwMTYgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAzICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMTM4X3N0YXRlXzIwMTcgPC0gc2FoaWVfMjAxNyAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDMgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAxMzhfc3RhdGVfMjAxOCA8LSBzYWhpZV8yMDE4ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMyAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKCnAyNTBfc3RhdGVfMjAwOCA8LSBzYWhpZV8yMDA4ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMiAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDI1MF9zdGF0ZV8yMDA5IDwtIHNhaGllXzIwMDkgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAyICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMjUwX3N0YXRlXzIwMTAgPC0gc2FoaWVfMjAxMCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDIgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAyNTBfc3RhdGVfMjAxMSA8LSBzYWhpZV8yMDExICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMiAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDI1MF9zdGF0ZV8yMDEyIDwtIHNhaGllXzIwMTIgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAyICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMjUwX3N0YXRlXzIwMTMgPC0gc2FoaWVfMjAxMyAlPiUKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMiAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDI1MF9zdGF0ZV8yMDE0IDwtIHNhaGllXzIwMTQgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAyICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMjUwX3N0YXRlXzIwMTUgPC0gc2FoaWVfMjAxNSAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDIgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAyNTBfc3RhdGVfMjAxNiA8LSBzYWhpZV8yMDE2ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMiAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDI1MF9zdGF0ZV8yMDE3IDwtIHNhaGllXzIwMTcgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAyICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMjUwX3N0YXRlXzIwMTggPC0gc2FoaWVfMjAxOCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDIgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCgpwMTM4X3N0YXRlXzA4MTggPC0gcmJpbmQocDEzOF9zdGF0ZV8yMDA4LCBwMTM4X3N0YXRlXzIwMDksIHAxMzhfc3RhdGVfMjAxMCwgcDEzOF9zdGF0ZV8yMDExLCBwMTM4X3N0YXRlXzIwMTIsIAogICAgICAgICAgICAgICAgICAgIHAxMzhfc3RhdGVfMjAxMywgcDEzOF9zdGF0ZV8yMDE0LCBwMTM4X3N0YXRlXzIwMTUsIHAxMzhfc3RhdGVfMjAxNiwgcDEzOF9zdGF0ZV8yMDE3LAogICAgICAgICAgICAgICAgICAgIHAxMzhfc3RhdGVfMjAxOCkKcDI1MF9zdGF0ZV8wODE4IDwtIHJiaW5kKHAyNTBfc3RhdGVfMjAwOCwgcDI1MF9zdGF0ZV8yMDA5LCBwMjUwX3N0YXRlXzIwMTAsIHAyNTBfc3RhdGVfMjAxMSwgcDI1MF9zdGF0ZV8yMDEyLCAKICAgICAgICAgICAgICAgICAgICBwMjUwX3N0YXRlXzIwMTMsIHAyNTBfc3RhdGVfMjAxNCwgcDI1MF9zdGF0ZV8yMDE1LCBwMjUwX3N0YXRlXzIwMTYsIHAyNTBfc3RhdGVfMjAxNywKICAgICAgICAgICAgICAgICAgICBwMjUwX3N0YXRlXzIwMTgpCnBfc3RhdGVfMDgxOCA8LSByYmluZChwMTM4X3N0YXRlXzA4MTgsIHAyNTBfc3RhdGVfMDgxOCkKYGBgCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGZpZy5hc3AgPSAxLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OH0KcDEgPC0gcF9zdGF0ZV8wODE4ICU+JSBtdXRhdGUoeWVhcj1hcy5mYWN0b3IoeWVhciksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcHJjYXQ9aWZlbHNlKGlwcmNhdD09MiwgIkF0IG9yIGJlbG93IDI1MCUgRlBMIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0IG9yIGJlbG93IDEzOCUgRlBMIikpICU+JQogIGdyb3VwX2J5KHllYXIsIGlwcmNhdCkgJT4lIHN1bW1hcmlzZShhdmcuVUkgPSBtZWFuKE5VSS9OSVBSKSkgJT4lCiAgZ2dwbG90KGFlcyh4PXllYXIsIHk9YXZnLlVJLCBncm91cD1pcHJjYXQsIGNvbG9yPWlwcmNhdCwKICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgnPC9icj4gWWVhcjogJywgeWVhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvYnI+IFVuaW5zdXJlZCBwZXJjZW50YWdlOiAnLCByb3VuZChhdmcuVUksMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2JyPiBJbmNvbWUgbGV2ZWw6ICcsIGlwcmNhdCkpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgdGhlbWVfZWNvbm9taXN0KCkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogIGxhYnModGl0bGU9Ik5hdGlvbmFsIHVuaW5zdXJhbmNlIHJhdGUgYnkgaW5jb21lIGxldmVsXG4iKSArCiAgeWxhYigiIikgKwogIHhsYWIoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZC5pdGFsaWMiLCBoanVzdCA9IDAuNSksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQoKZ2dwbG90bHkocDEsIHRvb2x0aXAgPSAidGV4dCIsIGhlaWdodCA9IDQwMCwgd2lkdGg9NzAwKSAlPiUgCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpICU+JQogIGxheW91dChob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3QoZmFtaWx5ID0gIkdlb3JnaWEiKSksIAogICAgICAgICBsZWdlbmQgPSBsaXN0KG9yaWVudGF0aW9uID0gImgiLCB5PTEuMDgpKQpgYGAKCgoKSG93IGFyZSBpbmNvbWUgbGV2ZWxzIHJlbGF0ZWQgdG8gdGhlIHVuaW5zdXJhbmNlIHJhdGU/IFdlIGNob3NlIHRvIGZvY3VzIG9uIHRoZSAxMzglIG9mIHRoZSBGZWRlcmFsIFBvdmVydHkgTGV2ZWwgKEZQTCkgYW5kIHRoZSAyNTAlIG9mIEZQTC4gVGhlIHJlYXNvbmluZyBpcyB0aGF0IGZvciB0aGUgcG9wdWxhdGlvbiB3aXRoIGluY29tZSBsZXZlbCBiZWxvdyB0aGUgMTM4JSBGUEwsIGlmIHRoZWlyIHN0YXRlcyBleHBhbmRlZCBNZWRpY2FpZCB1bmRlciB0aGUgQWZmb3JkYWJsZSBDYXJlIEFjdCAoQUNBLCBzaWduZWQgaW50byBsYXcgYnkgUHJlc2lkZW50IE9iYW1hIGluIDIwMTAgYW5kIHdlbnQgaW50byBlZmZlY3Qgc3RhcnRpbmcgMjAxNCksIHRoZXkgbWF5IHF1YWxpZnkgZm9yIE1lZGljYWlkIG9yIENISVAuIFBvcHVsYXRpb24gdGhhdCBlYXJucyBhbiBpbmNvbWUgYmVsb3cgdGhlIDI1MCUgRlBMIG1heSBxdWFsaWZ5IGZvciBvdXQtb2YtcG9ja2V0IGNvc3QgYXNzaXN0YW5jZSBvbiBTaWx2ZXIgcGxhbnMgc29sZCB0aHJvdWdoIHRoZSBNYXJrZXRwbGFjZS4gCgpGcm9tIHRoZSBhYm92ZSBncmFwaGljLCB3ZSBjYW4gc2VlIHRoYXQgdGhlIGxvd2VyIHRoZSBpbmNvbWUsIGFsdGhvdWdoIHdpdGggc29tZSBsZXZlbCBvZiBhc3Npc3RhbmNlLCB0aGUgaGlnaGVyIHVuaW5zdXJhbmNlIHJhdGUgYWNyb3NzIHRoZSAxMCB5ZWFyIHBlcmlvZC4gV2UgY2FuIGFsc28gb2JzZXJ2ZSBjbGVhcmx5IHRoYXQgdGhlIHVuaW5zdXJhbmNlIHJhdGUgZHJvcHBlZCBzaWduaWZpY2FudGx5IGJldHdlZW4gMjAxMyBhbmQgMjAxNCwgYmVjYXVzZSBvZiB0aGUgQUNBLgoKKipIb3ZlciBvdmVyIGRhdGEgcG9pbnRzIG9mIGludGVyZXN0KioKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYXNwID0gMSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTh9CmluY29tZSA8LSByZWFkLmNzdigiRGF0YS9Ib25nanVlX0JFQV9JbmNvbWVfUGVyX0NhcGl0YV9ieV9TdGF0ZV8xOTkwLTIwMTkuY3N2IikKCmluY29tZSA8LSBpbmNvbWUgJT4lIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoR2VvRmlwcykgPCA1LCBwYXN0ZTAoMCwgR2VvRmlwcyksIEdlb0ZpcHMpKSAlPiUKICBzZWxlY3QoLUdlb0ZpcHMpICU+JQogIGZpbHRlcih5ZWFyICVpbiUgMjAwODoyMDE4KQoKc3RhdGVfc2ltcGxlIDwtIHN0YXRlXzA4MTggJT4lIHNlbGVjdCh5ZWFyLCBOVUksIE5JUFIsIGZpcHMpCgppbmNfaW5zdXIgPC0gbGVmdF9qb2luKGluY29tZSwgc3RhdGVfc2ltcGxlKQoKcDIgPC0gZ2dwbG90KGluY19pbnN1ciwgYWVzKHg9TlVJL05JUFIsIHk9aW5jb21lX3Blcl9jYXBpdGEsIGNvbG9yPUdlb05hbWUsIGFscGhhPTAuNywgc2hhcGU9YXMuZmFjdG9yKHllYXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCc8L2JyPiBZZWFyOiAnLCB5ZWFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2JyPiBTdGF0ZTogJywgR2VvTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9icj4gVW5pbnN1cmVkIHBlcmNlbnRhZ2U6ICcsIHJvdW5kKE5VSS9OSVBSLDIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2JyPiBJbmNvbWUgbGV2ZWw6ICcsIGluY29tZV9wZXJfY2FwaXRhKSkpICsKICBnZW9tX3BvaW50KCkgKwogIHRoZW1lX2Vjb25vbWlzdCgpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2QoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gZG9sbGFyKSArCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkLml0YWxpYyIsIGhqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBsYWJzKHRpdGxlID0gIkhvdyBkb2VzIGluY29tZSBhZmZlY3QgdGhlIHVuaW5zdXJhbmNlIHJhdGU/Iiwgc3VidGl0bGUgPSAiU3RhdGVzIGJ5IGNvbG9yLCB5ZWFycyBieSBzaGFwZSIpICsKICB4bGFiKCJSYXRlIG9mIHVuaW5zdXJhbmNlIikgKyAKICB5bGFiKCJJbmNvbWUgcGVyIGNhcGl0YVxuIikKCmdncGxvdGx5KHAyLCB0b29sdGlwID0gInRleHQiLCBoZWlnaHQgPSA0MDAsIHdpZHRoPTc4MCkgJT4lIAogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKSAlPiUKICBsYXlvdXQoaG92ZXJsYWJlbCA9IGxpc3QoYmdjb2xvciA9ICJ3aGl0ZSIsIGZvbnQgPSBsaXN0KGZhbWlseSA9ICJHZW9yZ2lhIikpKQpgYGAKCgpIZXJlIGlzIGEgbW9yZSBkZXRhaWxlZCBsb29rIGludG8gdGhpcyBpbmNvbWUtdW5pbnN1cmFuY2UgcmVsYXRpb25zaGlwLiBXZSBjYW4gc2VlIHRoYXQsIGluIGdlbmVyYWwsIHRoZSBsb3dlciB0aGUgaW5jb21lIHBlciBjYXBpdGEgKG9mIGEgY2VydGFpbiBzdGF0ZSBpbiBhIGdpdmVuIHllYXIpLCB0aGUgaGlnaGVyIHRoZSBzdGF0ZS1sZXZlbCB1bmluc3VyZWQgcmF0ZS4gKE5vdGU6IFN0YXRlcyBhcmUgZGlmZmVyZW50aWF0ZWQgdXNpbmcgY29sb3IgYW5kIHllYXJzIGFyZSBkaWZmZXJlbnRpYXRlZCB1c2luZyBzaGFwZS4pCiAgCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpzdGF0ZXMgPC0gcmVhZE9HUihkc24gPSAiRGF0YS9nel8yMDEwX3VzXzA0MF8wMF81MDBrLmpzb24iKQoKZHQgPC0gaW5jX2luc3VyICU+JQogIG11dGF0ZSh5ZWFyPWFzLmZhY3Rvcih5ZWFyKSwgdW5pbnN1cmVkID0gcm91bmQoTlVJL05JUFIsMiksIHN0YXRlID0gYXMuY2hhcmFjdGVyKEdlb05hbWUpKSAlPiUgCiAgc2VsZWN0KHllYXIsIHN0YXRlLCB1bmluc3VyZWQsIGluY29tZV9wZXJfY2FwaXRhKSAlPiUgZmlsdGVyKHllYXI9PTIwMDgpCgpkdC5nZW8gPC0gZHQgJT4lIG11dGF0ZV9nZW9jb2RlKHN0YXRlKQpgYGAKClRvIHZpc3VhbGl6ZSB0aGlzIGluIGEgbWFwLCB3ZSBjcmVhdGVkIGEgTGVhZmxldCBtYXAgd2l0aCBzZXBhcmF0ZSBsYXllcnMgZm9yIHRoZSB1bmluc3VyYW5jZSByYXRlIGFuZCBpbmNvbWUgbGV2ZWwsIHNob3duIGJlbG93IGZvciB0aGUgeWVhciAyMDA4LiBVc2luZyB0aGlzIHZpc3VhbGl6YXRpb24gd2UgY2FuIG9ic2VydmUgdGhhdCBpbiBnZW5lcmFsLCB0aGUgbm9ydGhlYXN0IGFuZCB3ZXN0IGNvYXN0IHJlZ2lvbnMgaGFkIGhpZ2hlciBpbmNvbWVzIHBlciBjYXBpdGEsIHdoaWxlIHRoZSBzb3V0aHMsIG1pZHdlc3QsIGFuZCBBbGFza2Egd2VyZSBzdHJ1Z2dsaW5nIHdpdGggdGhlIGhpZ2hlc3QgdW5pbnN1cmFuY2UgcmF0ZS4gCgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmR0IDwtIGluY19pbnN1ciAlPiUKICBtdXRhdGUodW5pbnN1cmVkID0gcm91bmQoTlVJL05JUFIsMiksIHN0YXRlID0gYXMuY2hhcmFjdGVyKEdlb05hbWUpKSAlPiUgCiAgc2VsZWN0KHllYXIsIHN0YXRlLCB1bmluc3VyZWQsIGluY29tZV9wZXJfY2FwaXRhKSAlPiUKICBtdXRhdGVfZ2VvY29kZShzdGF0ZSkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTZ9CiMgZHRfeWVhciA8LSBkdCAlPiUgZmlsdGVyKHllYXI9PTIwMDgpCmR0X3llYXIgPC0gZHQgJT4lIGdyb3VwX2J5KHN0YXRlKSAlPiUgCiAgc3VtbWFyaXNlKGluY29tZV9wZXJfY2FwaXRhPW1lYW4oaW5jb21lX3Blcl9jYXBpdGEpLCB1bmluc3VyZWQ9bWVhbih1bmluc3VyZWQpLCAKICAgICAgICAgICAgbG9uPW1lYW4obG9uKSwgbGF0PW1lYW4obGF0KSkgJT4lCiAgbXV0YXRlKHN0YXRlPWFzLmZhY3RvcihzdGF0ZSkpCgpzdGF0ZXMubWVyZ2VkIDwtIG1lcmdlKHg9c3RhdGVzLCB5PWR0X3llYXIsIGJ5Lng9Ik5BTUUiLCBieS55PSJzdGF0ZSIpCgpwYWwxIDwtIGNvbG9yQmluKCJZbE9yUmQiLCBkb21haW4gPSBzdGF0ZXMubWVyZ2VkJHVuaW5zdXJlZCwgYmlucyA9IGMoMCwgMC4wNSwgMC4xLCAwLjE1LCAwLjIsIDAuMjUsIDAuMykpCnBhbDIgPC0gY29sb3JCaW4oIkJ1R24iLCBkb21haW4gPSBzdGF0ZXMubWVyZ2VkJGluY29tZV9wZXJfY2FwaXRhLCBiaW5zID0gYygyMDAwMDo4NTAwMCkpCgpwb3B1cCA9IHBhc3RlKCJTdGF0ZTogIiwgc3RhdGVzLm1lcmdlZEBkYXRhJE5BTUUsCiAgICAgICAgICAgICAgIjxicj5JbmNvbWUgcGVyIGNhcGl0YTogIiwgcm91bmQoc3RhdGVzLm1lcmdlZEBkYXRhJGluY29tZV9wZXJfY2FwaXRhLDIpLAogICAgICAgICAgICAgICI8YnI+VW5pbnN1cmVkIHJhdGU6ICIsIHJvdW5kKHN0YXRlcy5tZXJnZWRAZGF0YSR1bmluc3VyZWQsMikpCgpsZWFmbGV0KHN0YXRlcy5tZXJnZWQpICU+JSBhZGRUaWxlcygpICU+JQogIHNldFZpZXcoLTk2LCAzNy44LCA0KSAlPiUKICBhZGRQb2x5Z29ucyhmaWxsQ29sb3IgPSB+cGFsMSh1bmluc3VyZWQpLAogICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNiwgY29sb3IgPSAiZGFya2dyZXkiLCB3ZWlnaHQgPSAxLjUsCiAgICAgICAgICAgIHBvcHVwID0gcG9wdXAsIGdyb3VwPSJVbmluc3VyZWQgcmF0ZSIpJT4lCiAgYWRkUG9seWdvbnMoZmlsbENvbG9yID0gfnBhbDIoaW5jb21lX3Blcl9jYXBpdGEpLCAKICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSAxLCBjb2xvciA9ICJ3aGl0ZSIsIHdlaWdodCA9IDIuMCwgCiAgICAgICAgICAgIHBvcHVwID0gcG9wdXAsIGdyb3VwPSJJbmNvbWUgbGV2ZWwiKSAlPiUKICBhZGRMYXllcnNDb250cm9sKAogICAgYmFzZUdyb3VwcyA9IGMoIlVuaW5zdXJhbmNlIHJhdGUiLCAiSW5jb21lIGxldmVsIiksCiAgICBvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gRkFMU0UpKQoKIyBoZWlnaHQ9IjEwMCUiLCB3aWR0aD0iMTAwJSIKYGBgCgpUbyBtYWtlIGl0IGNsZWFyZXIgYW5kIGVhc2llciB0byB1bmRlcnN0YW5kLCB3ZSBjcmVhdGVkIGEgZGF0YSB0YWJsZSBmb3Igb3VyIHVzZXJzIHRvIGV4cGxvcmUgdGhlIHN0YXRpc3RpY3Mgb2YgdGhlaXIgaW50ZXJlc3Q6CgpgYGB7ciwgZXZhbD1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkdCA8LSBpbmNfaW5zdXIgJT4lCiAgbXV0YXRlKHllYXI9YXMuZmFjdG9yKHllYXIpLCB1bmluc3VyZWQgPSByb3VuZChOVUkvTklQUiwyKSkgJT4lIAogIHNlbGVjdCh5ZWFyLCBHZW9OYW1lLCB1bmluc3VyZWQsIGluY29tZV9wZXJfY2FwaXRhKSAKCmNvbG5hbWVzKGR0KSA8LSBjKCJZZWFyIiwgIlN0YXRlIE5hbWUiLCAiVW5pbnN1cmFuY2UgUmF0ZSIsICJJbmNvbWUgcGVyIENhcGl0YSIpCgpkdCAlPiUKICBkYXRhdGFibGUoCiAgICBmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIpLAogICAgb3B0aW9ucyA9IGxpc3QobGFuZ3VhZ2UgPSBsaXN0KHNTZWFyY2ggPSAiRmlsdGVyOiIpKSkKYGBgCg==